package srzy.common

import scala.util.parsing.combinator._
import srzy.data.CaseInfo
import srzy.data.CdrInfo

object CaseFileParser extends RegexParsers {
  override def skipWhitespace = false
  def `\n` = """ *(\r?\n)*""".r
  def `:` = """: *(\r?\n)?""".r

  def item: Parser[String] = """[[\u0000-\uffff]&&[^\n]]*""".r ^^ { _.toString() }
  def block: Parser[String] = """[\u0000-\uffff]*""".r ^^ { _.toString() }
  //  def cdr: 
  def document: Parser[CaseInfo] = ("CaseName:" ~> item <~ `\n`) ~
    ("CaseDesc:" ~> item <~ `\n`) ~
    ("CaseType:" ~> item <~ `\n`) ~
    (("Input:" ~ `\n`) ~> items <~ `\n`) ~
    (cdrGroups <~ `\n`) ~
    (("InitShell:" ~ `\n`) ~> block) ^^
    {
      case _caseName ~ _caseDesc ~ _caseType ~ _input ~ m ~ _initShell =>
        new CaseInfo {
          caseName = _caseName
          caseDesc = _caseDesc
          caseType = _caseType
          initShell = _initShell
          input = _input
          normalCdr = m.get("NormalCdr").getOrElse(new CdrInfo())
          errCdr = m.get("ErrCdr").getOrElse(new CdrInfo())
          transCdr = m.get("TransCdr").getOrElse(new CdrInfo())
        }
    }

  def document1: Parser[CaseInfo] = ("CaseName:" ~> item <~ `\n`) ~
    ("CaseDesc:" ~> item <~ `\n`) ~
    ("CaseType:" ~> item <~ `\n`) ~
    (("Input:" ~ `\n`) ~> items <~ `\n`) ~
    (cdrGroups <~ `\n`) ~
    (("InitShell:" ~ `\n`) ~> block) ^^
    {
      case _ =>
        new CaseInfo {
          //          caseName = _caseName
          //          caseDesc = _caseDesc
          //          caseType = _caseType
          //          initShell = _initShell
          //          input = _input
          //          normalCdr = m.get("NormalCdr").getOrElse(List[CdrInfo]())
          //          errCdr = m.get("ErrCdr").getOrElse(List[CdrInfo]())
          //          transCdr = m.get("TransCdr").getOrElse(List[CdrInfo]())
        }
    }

  def items: Parser[List[String]] = repsep("  " ~> item, `\n`) ^^
    { _.toList } | "" ^^ { _ => List[String]() }

  def cdrGroup: Parser[(String, CdrInfo)] =
    ("NormalCdr" | "ErrCdr" | "TransCdr") ~ ":" ~ `\n` ~ items ^^ {
      case a ~ b ~ c ~ d => (a, new CdrInfo {
        stdFull = d
      })
    }

  def cdrGroups: Parser[Map[String, CdrInfo]] =
    repsep(cdrGroup, `\n`) ^^ { _.toMap }

  //  def cdrItems: Parser[List[CdrInfo]] = repsep("""[[A-Za-z0-9]&&[^:]]*""".r ~ ":" ~ `\n` ~ cdrItem, `\n`)

  def parse(text: String): CaseInfo = {
    parseAll(document, text) match {
      case Success(r, _) => r
      case Failure(msg, _) => throw new Exception("CaseInfo Parser failure :" + msg)
      case Error(msg, _) => throw new Exception("CaseInfo Parser error :" + msg)
    }
  }
}
